﻿using System;
using System.Configuration;
using System.Globalization;
using System.IO;
using System.Net;
using System.Text;
using System.Web;
using ImageResizer;
using MSAcademic.v2.Infrastructure.Utility;
using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Auth;
using Microsoft.WindowsAzure.Storage.Blob;

namespace MSAcademic.v2.Infrastructure.Picture.Impl
{
    public partial class BlobPictureService : IPictureService
    {
        public void UserProfilePictureUpload(int userId, HttpPostedFileBase userPicture)
        {
            var path = FilePath + "Users/" + userId;
            
            if (userPicture != null)
            {
                var pictureByteArray = ToByteArray(userPicture);
                var pictureWidth = ConfigurationManager.AppSettings["UserProfilePictureDefaultWidth"];

                var resizeQuerystring = @"?W=" + pictureWidth + "&Mode=Stretch&Scale=Both";
                var resizedPicture = ResizePicture(pictureByteArray, resizeQuerystring);

                path += @"/" + resizedPicture.Length + userPicture.FileName;
                var blockBlob = _cloudBlobContainer.GetBlockBlobReference(path);

                using (var stream = new MemoryStream(resizedPicture))
                {
                    blockBlob.UploadFromStream(stream);
                }
                _pictureCommands.SetUserProfilePicture(userId, blockBlob.Uri.ToString());
               
            }
        }
        public void ArticleFrontPictureUpload(int articleId, HttpPostedFileBase frontPicture)
        {
            var path = FilePath + @"Articles/" + articleId.ToString(CultureInfo.InvariantCulture);
            if (frontPicture != null)
            {
                var pictureByteArray = ToByteArray(frontPicture);
                var pictureWidth = ConfigurationManager.AppSettings["ArticleFrontPictureDefaultMaxWidth"];

                var resizeQuerystring = @"?W=" + pictureWidth + "&Mode=Stretch&Scale=Both";
                var resizedPicture = ResizePicture(pictureByteArray, resizeQuerystring);

                path += @"/" + pictureByteArray.Length.ToString(CultureInfo.InvariantCulture) + "-" + frontPicture.FileName;
                CloudBlockBlob blockBlob = _cloudBlobContainer.GetBlockBlobReference(path); 

                using (var stream = new MemoryStream(resizedPicture))
                {
                    blockBlob.UploadFromStream(stream);
                }

                _pictureCommands.SetArticleThumbnailPictureUrl(articleId, blockBlob.Uri.ToString());
                _pictureCommands.SetArticleNormalPictureUrl(articleId, blockBlob.Uri.ToString());
                _pictureCommands.SetArticleBigPictureUrl(articleId, blockBlob.Uri.ToString());
            }

        }

        public string GalleryPictureUpload(HttpPostedFileBase picture, int galleryId)
        {
            var path = FilePath + "Galleries/" + galleryId.ToString(CultureInfo.InvariantCulture);
            var resizeQuerystring = @"?MaxWidth=" + ConfigurationManager.AppSettings["ArticleGalleryPictureMaxWidth"] + "&MaxHeight=" + ConfigurationManager.AppSettings["ArticleGalleryPictureMaxHeight"];
            
            var pictureByteArray = ToByteArray(picture);
            var resizedPicture = ResizePicture(pictureByteArray, resizeQuerystring);

            path += @"/" + pictureByteArray.Length.ToString(CultureInfo.InvariantCulture) + "-" + picture.FileName;
            if (File.Exists(Path.Combine(HttpContext.Current.Server.MapPath(@"~/"), path)))
            {
                var fileName = Path.GetFileName(path);
                if (fileName != null)
                {
                    var newPicName = fileName.Replace(Path.GetFileNameWithoutExtension(path),
                                                      Path.GetFileNameWithoutExtension(path) +
                                                      RandomPictureIdentifier(4));

                    path = FilePath + "Galleries/" + galleryId.ToString(CultureInfo.InvariantCulture) +
                           @"/" + newPicName.ToLower();
                }
            }

            var blockBlob = _cloudBlobContainer.GetBlockBlobReference(path);
            using (var stream = new MemoryStream(resizedPicture))
            {
                blockBlob.UploadFromStream(stream);
            }
            return blockBlob.Uri.ToString();
        }
        public string DownloadAndUploadPictureToGallery(string url, int galleryId)
        {
            var path = FilePath + "Galleries/" + galleryId.ToString(CultureInfo.InvariantCulture);
            var resizeQuerystring = @"?MaxWidth=" + ConfigurationManager.AppSettings["ArticleGalleryPictureMaxWidth"] + "&MaxHeight=" + ConfigurationManager.AppSettings["ArticleGalleryPictureMaxHeight"];

            var client = new WebClient();
            var pic = client.DownloadData(new Uri(url));
            if (pic.Length > 0)
            {
                var resizedPicture = ResizePicture(pic, resizeQuerystring);
                path += @"/" +
                        _nonceGenerator.GetNewWithoutSpecialChars(
                            Convert.ToInt32(ConfigurationManager.AppSettings["GalleryPictureNameLegth"])) +
                        RandomPictureIdentifier(10) + Path.GetExtension(url);

                var blockBlob = _cloudBlobContainer.GetBlockBlobReference(path);
                using (var stream = new MemoryStream(resizedPicture))
                {
                    blockBlob.UploadFromStream(stream);
                }
                return blockBlob.Uri.ToString();
            }
            return "-1";
        }
        public string DownloadAndUploadUserProfilePicture(string url, int userId)
        {
            var path = FilePath + "Users/" + userId;
            
            var client = new WebClient();
            var picture = client.DownloadData(new Uri(url));
            if (picture.Length > 0)
            {
                var resizeQuerystring = @"?W=" + ConfigurationManager.AppSettings["UserProfilePictureDefaultWidth"] + "&Mode=Stretch&Scale=Both";
                var resizedPicture = ResizePicture(picture, resizeQuerystring);
                path += resizedPicture.Length + RandomPictureIdentifier(10);
                var blockBlob = _cloudBlobContainer.GetBlockBlobReference(path);
                using (var stream = new MemoryStream(resizedPicture))
                {
                    blockBlob.UploadFromStream(stream);
                }
                _pictureCommands.SetUserProfilePicture(userId, path);
                return blockBlob.Uri.ToString();
            }
            return "-1";

        }
    }
    public partial class BlobPictureService
    {
        public byte[] ToByteArray(HttpPostedFileBase picture)
        {
            var pictureByteArray = new byte[picture.ContentLength];
            picture.InputStream.Read(pictureByteArray, 0, picture.ContentLength);
            return pictureByteArray;
        }
        public byte[] ResizePicture(byte[] pictureByteArray, string resizeQuerystring)
        {
            using (var outputStream = new MemoryStream())
            {
                using (var inputStream = new MemoryStream(pictureByteArray))
                {
                    var settings = new ResizeSettings(resizeQuerystring);
                    ImageBuilder.Current.Build(inputStream, outputStream, settings);
                    return outputStream.ToArray();
                }
            }

        }
        public string GetOriginalPictureUrl(string path)
        {
            path = path.Replace("cropedthumbnail", "").Replace("cropednormal", "").Replace("cropedbig", "").Replace("gallerycroped", "").Replace("profilecroped","");
            return path;
        }
        private string RandomPictureIdentifier(int size)
        {
            var builder = new StringBuilder();
            for (var i = 0; i < size; i++)
            {
                var ch = Convert.ToChar(Convert.ToInt32(Math.Floor(26 * Random.NextDouble() + 65)));
                builder.Append(ch);
            }

            return builder.ToString();
        }
        public void SaveCroppedPicture(string pictureName, string pictureQuerystringUrl, string originalUrl)
        {
            //var destinationUrl = Path.Combine(HttpContext.Current.Server.MapPath("~/"), originalUrl);
            var destinationUrl = originalUrl.Replace(Path.GetFileNameWithoutExtension(originalUrl), pictureName);

            if (pictureQuerystringUrl != null)
            {   
                //get the picture from cloud service as a stream and rewind the stream
                var originalPictureBlob = new CloudBlockBlob(new Uri(originalUrl));
                var originalPictureStream = new MemoryStream();
                originalPictureBlob.DownloadToStream(originalPictureStream);
                originalPictureStream.Seek(0, SeekOrigin.Begin);

                //build the cropped picture, save into stream, rewind
                var uploadStream = new MemoryStream();
                ImageBuilder.Current.Build(originalPictureStream, uploadStream,
                                           new ResizeSettings(pictureQuerystringUrl.Split('?')[1]), false);
                uploadStream.Seek(0, SeekOrigin.Begin);
                //upload the built picture to the cloud
                var blockBlob = _cloudBlobContainer.GetBlockBlobReference(destinationUrl);
                blockBlob.UploadFromStream(uploadStream);
            }
            
        }

    }
    public partial class BlobPictureService
    {
        public string BuildCropedPicture(string queryString, string originalUrl, string type)
        {
            originalUrl = GetOriginalPictureUrl(originalUrl);

            var cropedPictureName = Path.GetFileNameWithoutExtension(originalUrl) + type;
            var savingPath = originalUrl.Replace(Path.GetFileNameWithoutExtension(originalUrl), cropedPictureName);

            SaveCroppedPicture(cropedPictureName, queryString, originalUrl);
            return savingPath;

        }
        
    }

    public partial class BlobPictureService
    {
        private static readonly Random Random = new Random((int)DateTime.Now.Ticks);
        private const string FilePath = @"Content/Uploads/Images/";
        private readonly IPictureCommands _pictureCommands;
        private readonly RandomNonceGenerator _nonceGenerator;
        private CloudStorageAccount _cloudStorageAccount;
        private CloudBlobClient _blobClient;
        private CloudBlobContainer _cloudBlobContainer;

        private void _setUpBlobStorage()
        {
            _cloudStorageAccount =
                CloudStorageAccount.Parse(ConfigurationManager.ConnectionStrings["MSAcademicBlobStorage"].ConnectionString);

            _blobClient = _cloudStorageAccount.CreateCloudBlobClient();

            _cloudBlobContainer = _blobClient.GetContainerReference("content");
        }

        public BlobPictureService(IPictureCommands pictureCommands,
            RandomNonceGenerator nonceGenerator)
        {
            _pictureCommands = pictureCommands;
            _nonceGenerator = nonceGenerator;
            _setUpBlobStorage();
        }
    }


}
